#include "stdafx.h"
#include "MFCControl.h"
#include "PlayerDialog.h"
#include "afxdialogex.h"
#include "MFCControlCtrl.h"

using namespace std;
using namespace DSP;

IMPLEMENT_DYNAMIC(CPlayerDialog, CDialog)

CPlayerDialog::CPlayerDialog(CWnd* pParent /*=NULL*/)
	: CDialog(CPlayerDialog::IDD, pParent)
{
}

CPlayerDialog::~CPlayerDialog()
{
}

void CPlayerDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_BUTTON_PLAY_PAUSE, m_ButtonPlay);
	DDX_Control(pDX, IDC_BUTTON_NEXT, m_ButtonNext);
	DDX_Control(pDX, IDC_BUTTON_PREVIOUS, m_ButtonPrevious);
	DDX_Control(pDX, IDC_BUTTON_STOP, m_ButtonStop);
	DDX_Control(pDX, IDC_BUTTON_MUTE, m_ButtonVolume);
	DDX_Control(pDX, IDC_BACKGROUND, m_Background);
	DDX_Control(pDX, IDC_VIDEO, m_VideoWindow);
	DDX_Control(pDX, IDC_PLAY_TIME, m_PlayTime);
	DDX_Control(pDX, IDC_SLIDER, m_PlaySlider);
	DDX_Control(pDX, IDC_VOLUME, m_VolumeSlider);
}

BOOL CPlayerDialog::OnInitDialog()
{
	CDialog::OnInitDialog();

	m_PlaySlider.m_PlayStatus=&m_PlayStatus;
	m_PlaySlider.m_CurPos=&m_CurPos;

	m_VolumeSlider.m_PlayStatus=&m_PlayStatus;
	m_VolumeSlider.m_CurPos=&m_CurPos;
	m_VolumeSlider.m_IsVolume=&m_IsVolume;
	m_VolumeSlider.m_CurVolume=&m_CurVolume;

	m_ButtonPlay.LoadButton(IDB_UP_PLAY,IDB_DOWN_PLAY,IDB_FOCUS_PLAY);
	m_ButtonStop.LoadButton(IDB_UP_STOP,IDB_DOWN_STOP,IDB_FOCUS_STOP);
	m_ButtonNext.LoadButton(IDB_UP_NEXT,IDB_DOWN_NEXT,IDB_FOCUS_NEXT);
	m_ButtonPrevious.LoadButton(IDB_UP_PREVIOUS,IDB_DOWN_PREVIOUS,IDB_FOCUS_PREVIOUS);
	m_ButtonVolume.LoadButton(IDB_UP_VOLUME,IDB_DOWN_VOLUME,IDB_FOCUS_VOLUME);
	m_IsHTML=false;
	if(m_FileName!="")
	{
		m_ButtonNext.ShowWindow(SW_HIDE);
		m_ButtonPrevious.ShowWindow(SW_HIDE);
		m_IsHTML=true;
	}
	m_PlayStatus=NO_FILE;
	m_IsVolume=true;
	m_CurVolume=100;

	m_VolumeSlider.SetRange(0,100);
	m_VolumeSlider.SetPos(100);
	m_AspectRatio=0;

	m_CurPos=0;

	m_IsFullScreen=false;

	return TRUE;
}

BEGIN_MESSAGE_MAP(CPlayerDialog, CDialog)
	ON_WM_CREATE()
	ON_WM_SIZE()
	ON_BN_CLICKED(IDC_BUTTON_PLAY_PAUSE, &CPlayerDialog::OnBnClickedButtonPlay)
	ON_BN_CLICKED(IDC_BUTTON_STOP, &CPlayerDialog::OnBnClickedButtonStop)
	ON_BN_CLICKED(IDC_BUTTON_MUTE, &CPlayerDialog::OnBnClickedButtonMute)
	ON_BN_CLICKED(IDC_BUTTON_NEXT, &CPlayerDialog::OnBnClickedButtonNext)
	ON_BN_CLICKED(IDC_BUTTON_PREVIOUS, &CPlayerDialog::OnBnClickedButtonPrevious)
	ON_WM_MOUSEMOVE()
	ON_WM_TIMER()
	ON_WM_DROPFILES()
	ON_WM_HSCROLL()
END_MESSAGE_MAP()

int CPlayerDialog::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CDialog::OnCreate(lpCreateStruct) == -1)
		return -1;

	this->DragAcceptFiles(true);

	return 0;
}

void CPlayerDialog::OnSize(UINT nType, int cx, int cy)
{
	CDialog::OnSize(nType, cx, cy);

	if(m_VideoWindow.GetSafeHwnd())
	{
		m_VideoWindow.MoveWindow(0,0,cx,cy-97);
		m_WinW=cx;
		m_WinH=cy-97;
		if(m_PlayStatus!=NO_FILE && m_PlayStatus!=FILE_STOP && m_IsVideo)
		{
			try
			{
				long m_VideoW, m_VideoH;
				if((double)m_WinW/(double)m_WinH<m_AspectRatio)
				{
					m_VideoW=m_WinW;
					m_VideoH=(long)(m_VideoW/m_AspectRatio);
					m_Video->setWindowPosition(0,(m_WinH-m_VideoH)/2,m_VideoW,m_VideoH);
				}
				else if((double)m_WinW/(double)m_WinH>m_AspectRatio)
				{
					m_VideoH=m_WinH;
					m_VideoW=(long)(m_VideoH*m_AspectRatio);
					m_Video->setWindowPosition((m_WinW-m_VideoW)/2,0,m_VideoW,m_VideoH);
				}
				else
				{
					m_Video->setWindowPosition(0,0,m_WinW,m_WinH);
				}
			}
			catch(const errorInfo& erInfo)
			{
				CString m_ErInfo(erInfo.what());
				MessageBox(m_ErInfo);
			}
		}
	}

	int x=cx;
	if(x<550 && !m_IsHTML)
		x=550;
	if(x<454 && m_IsHTML)
		x=454;

	if(m_ButtonPlay.GetSafeHwnd())
		m_ButtonPlay.MoveWindow(x/2-33,cy-70,66,66);
	if(m_IsHTML && m_FileName!="")
	{
		if(m_ButtonStop.GetSafeHwnd())
			m_ButtonStop.MoveWindow(x/2-81,cy-59,44,44);
		if(m_ButtonVolume.GetSafeHwnd())
			m_ButtonVolume.MoveWindow(x/2+37,cy-59,44,44);
	}
	else
	{
		if(m_ButtonNext.GetSafeHwnd())
			m_ButtonNext.MoveWindow(x/2+37,cy-59,44,44);
		if(m_ButtonPrevious.GetSafeHwnd())
			m_ButtonPrevious.MoveWindow(x/2-81,cy-59,44,44);
		if(m_ButtonStop.GetSafeHwnd())
			m_ButtonStop.MoveWindow(x/2-129,cy-59,44,44);
		if(m_ButtonVolume.GetSafeHwnd())
			m_ButtonVolume.MoveWindow(x/2+85,cy-59,44,44);
	}
	if(m_Background.GetSafeHwnd())
		m_Background.MoveWindow(0,cy-80,x,80);
	if(m_PlaySlider.GetSafeHwnd())
		m_PlaySlider.MoveWindow(0,cy-97,x,17);
	if(m_PlayTime.GetSafeHwnd())
		m_PlayTime.MoveWindow(20,cy-45,110,16);
	if(m_VolumeSlider.GetSafeHwnd())
		m_VolumeSlider.MoveWindow(x-130,cy-45,110,16);
}

void CPlayerDialog::OnBnClickedButtonPlay()
{
	if(m_PlayStatus==NO_FILE)
	{
		if(m_IsHTML)
		{
			StartPlaying();
		}
		else
		{
			CMFCControlCtrl* p=(CMFCControlCtrl*)this->GetParent();
			p->OnNextTrack();
		}
	}
	else if(m_PlayStatus==FILE_PLAY)
	{
		try
		{
			m_Player->pause();
			m_ButtonPlay.LoadButton(IDB_UP_PLAY,IDB_DOWN_PLAY,IDB_FOCUS_PLAY);
			m_PlayStatus=FILE_PAUSE;
		}
		catch(const errorInfo& erInfo)
		{
			CString m_ErInfo(erInfo.what());
			MessageBox(m_ErInfo);
		}
	}
	else if(m_PlayStatus==FILE_PAUSE)
	{
		try
		{
			m_Player->play();
			m_ButtonPlay.LoadButton(IDB_UP_PAUSE,IDB_DOWN_PAUSE,IDB_FOCUS_PAUSE);
			m_PlayStatus=FILE_PLAY;
		}
		catch(const errorInfo& erInfo)
		{
			CString m_ErInfo(erInfo.what());
			MessageBox(m_ErInfo);
		}
	}
	else if(m_PlayStatus==FILE_STOP)
	{
		StartPlaying();
	}
}

void CPlayerDialog::OnBnClickedButtonStop()
{
	if(m_PlayStatus!=NO_FILE)
	{
		try
		{
			StopPlaying();
		}
		catch(const errorInfo& erInfo)
		{
			CString m_ErInfo(erInfo.what());
			MessageBox(m_ErInfo);
		}
	}
}

void CPlayerDialog::OnBnClickedButtonMute()
{
	if(m_IsVolume)
	{
		m_IsVolume=false;
		m_ButtonVolume.LoadButton(IDB_UP_NO_VOLUME,IDB_DOWN_NO_VOLUME,IDB_FOCUS_NO_VOLUME);
		if(m_PlayStatus!=NO_FILE)
		{
			try
			{
				m_Player->setVolume(0);
			}
			catch(const errorInfo& erInfo)
			{
				CString m_ErInfo(erInfo.what());
				MessageBox(m_ErInfo);
			}
		}
	}
	else
	{
		m_IsVolume=true;
		m_ButtonVolume.LoadButton(IDB_UP_VOLUME,IDB_DOWN_VOLUME,IDB_FOCUS_VOLUME);
		if(m_PlayStatus!=NO_FILE)
		{
			try
			{
				m_Player->setVolume(m_CurVolume);
			}
			catch(const errorInfo& erInfo)
			{
				CString m_ErInfo(erInfo.what());
				MessageBox(m_ErInfo);
			}
		}
	}
}

void CPlayerDialog::OnBnClickedButtonNext()
{
	CMFCControlCtrl* p=(CMFCControlCtrl*)this->GetParent();
	p->OnNextTrack();
}


void CPlayerDialog::OnBnClickedButtonPrevious()
{
	CMFCControlCtrl* p=(CMFCControlCtrl*)this->GetParent();
	p->OnPreviousTrack();
}

void CPlayerDialog::OnMouseMove(UINT nFlags, CPoint point)
{
	TRACKMOUSEEVENT tme;
    tme.cbSize = sizeof(tme);
    tme.hwndTrack = m_hWnd;
    tme.dwFlags = TME_LEAVE|TME_HOVER;
    tme.dwHoverTime = 1;
    TrackMouseEvent(&tme);
	CDialog::OnMouseMove(nFlags, point);
}

void CPlayerDialog::OnTimer(UINT nIDEvent)
{
	if(m_PlayStatus==FILE_PLAY)
	{
		LONGLONG m_curPos;
		try
		{
			m_Player->getCurrentPosition(m_curPos);
			m_CurPos=(int)m_curPos;
			m_PlaySlider.SetPos(m_CurPos);
			SetDlgItemTextW(IDC_PLAY_TIME,GetTimeString(m_CurPos));
		}
		catch(const errorInfo& erInfo)
		{
			CString m_ErInfo(erInfo.what());
			MessageBox(m_ErInfo);
		}
	}

	if(m_CurPos>=m_SliderMax)
	{
		try
		{
			StopPlaying();
		}
		catch(const errorInfo& erInfo)
		{
			CString m_ErInfo(erInfo.what());
			MessageBox(m_ErInfo);
		}
		if(!m_IsHTML)
			OnBnClickedButtonStop();
	}

	CDialog::OnTimer(nIDEvent);
}

void CPlayerDialog::OnDropFiles(HDROP hDropInfo)
{
	CMFCControlCtrl* p=(CMFCControlCtrl*)this->GetParent();
	p->OnDelPlaylist();
	int m_nFiles = DragQueryFile(hDropInfo, (UINT)-1, NULL, 0);

	for (int i=0; i<m_nFiles; i++)
	{
		TCHAR szFileName[_MAX_PATH];
		::DragQueryFile(hDropInfo, i, szFileName, _MAX_PATH);

		BSTR FileName=SysAllocString(szFileName);
		p->OnAddFile(&FileName);
	}
	p->OnNextTrack();
}

void CPlayerDialog::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	if(pScrollBar->GetSafeHwnd()==m_PlaySlider.GetSafeHwnd())
		m_PlaySlider.OnHScroll(nSBCode, nPos, pScrollBar);
	if(pScrollBar->GetSafeHwnd()==m_VolumeSlider.GetSafeHwnd())
		m_VolumeSlider.OnHScroll(nSBCode, nPos, pScrollBar);

	CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

LRESULT CPlayerDialog::OnBitmapSliderMoving(WPARAM wParam, LPARAM lParam)
{
		m_CurPos = m_PlaySlider.GetPos();
		UpdateData( FALSE );

		return 0;
}


void CPlayerDialog::StartPlaying(void)
{
	try
	{
		smartCOM sCOM;
		m_Player.reset(new DSplayer<simpleGraph>(new simpleGraph(m_FileName)));
		m_PlaySlider.m_Player=m_Player;
		m_VolumeSlider.m_Player=m_Player;
		if(m_Player->getVideo())
		{
			m_Video=m_Player->getVideo();
			m_Video->setVideoWindow(m_VideoWindow.GetSafeHwnd());
			m_AspectRatio=m_Video->getAspectRatio();
			m_IsVideo=true;
		}
		else
			m_IsVideo=false;
		if(m_IsVolume)
			m_Player->setVolume(m_CurVolume);
		else
			m_Player->setVolume(0);

		m_Player->seek(m_CurPos);
		m_Player->play();
		m_PlayStatus=FILE_PLAY;
		this->OnSize(0,m_WinW,m_WinH+97);

		LONGLONG m_Duration;
		m_Player->getDuration(m_Duration);
		m_SliderMax=(int)m_Duration;
		m_PlaySlider.SetRangeMax(m_SliderMax);
		SetTimer(1,1000,NULL);
		m_ButtonPlay.LoadButton(IDB_UP_PAUSE,IDB_DOWN_PAUSE,IDB_FOCUS_PAUSE);
		SetMaxTimeString(m_SliderMax);
		SetDlgItemTextW(IDC_PLAY_TIME,GetTimeString(0));
	}
	catch(const errorInfo& erInfo)
	{
		CString m_ErInfo(erInfo.what());
		MessageBox(m_ErInfo);
	}
}

void CPlayerDialog::StopPlaying(void)
{
	try
	{
		m_Player->stop();
		KillTimer(1);
		m_PlayStatus=FILE_STOP;
		m_CurPos=0;
		m_PlaySlider.SetPos(m_CurPos);
		m_ButtonPlay.LoadButton(IDB_UP_PLAY,IDB_DOWN_PLAY,IDB_FOCUS_PLAY);
		RedrawWindow();
		SetDlgItemTextW(IDC_PLAY_TIME,L"");
	}
	catch(const errorInfo& erInfo)
	{
		CString m_ErInfo(erInfo.what());
		MessageBox(m_ErInfo);
	}
}


CString CPlayerDialog::GetTimeString(int sec)
{
	CString m_Time=SecToString(sec);
	m_Time+=L"/";
	m_Time+=m_MaxTime;
	
	return m_Time;
}

void CPlayerDialog::SetMaxTimeString(int sec)
{
	if(sec>=3600)
		m_HourMode=true;
	else
		m_HourMode=false;
	m_MaxTime=SecToString(sec);
}

CString CPlayerDialog::SecToString(int sec)
{
	CString m_sTime, m_smin, m_ssec;
	int m_sec, m_min, m_hour;
	
	m_min=sec/60;
	m_sec=sec-m_min*60;
	m_hour=m_min/60;
	m_min-=m_hour*60;

	if(m_sec<10)
		m_ssec.Format(_T("0%d"),m_sec);
	else
		m_ssec.Format(_T("%d"),m_sec);

	if(m_min<10)
		m_smin.Format(_T("0%d"),m_min);
	else
		m_smin.Format(_T("%d"),m_min);

	if(m_HourMode)
	{
		m_sTime.Format(_T("%d"),m_hour);
		m_sTime+=L":";
	}
	m_sTime+=m_smin;
	m_sTime+=L":";
	m_sTime+=m_ssec;


	return m_sTime;
}
